package decorator

import "strings"

// Component 组件对象的接口，可以给这些对象动态地添加职责
type Component interface {
	// Operation 示例方法
	Operation() string
}

// ConcreteComponent 具体实现组件对象接口的对象
type ConcreteComponent struct {
}

func (c *ConcreteComponent) Operation() string {
	// 相应的功能处理
	return "ConcreteComponent"
}

// DecoratorA 装饰器的具体实现对象，向组件对象添加职责
type DecoratorA struct {
	Component        // 持有组件对象
	state     string // 添加的状态
}

// NewDecoratorA 构造方法，传入组件对象
func NewDecoratorA(component Component, state string) *DecoratorA {
	return &DecoratorA{
		Component: component,
		state:     state,
	}
}

func (d *DecoratorA) Operation() string {
	// 转发请求给 组件对象，可以在前后执行一些附加动作
	return strings.Replace(d.Component.Operation()+d.state, "Concrete", "c", 1)
}

// DecoratorB 装饰器的具体实现对象，向组件对象添加职责
type DecoratorB struct {
	Component        // 持有组件对象
	state     string // 添加的状态
}

// NewDecoratorB 构造方法，传入组件对象
func NewDecoratorB(component Component, state string) *DecoratorB {
	return &DecoratorB{
		Component: component,
		state:     state,
	}
}

func (d *DecoratorB) Operation() string {
	// 转发请求给 组件对象，可以在前后执行一些附加动作
	return strings.ToUpper(d.Component.Operation() + d.state)
}
